package com.eshipenet.shipnet.equipmentdatahub
import play.api.libs.json.{Format, JsObject, JsValue, Json}

import scala.util.{Failure, Success, Try}

object EquipmentWithModel {

//  implicit val format: Format[EquipmentWithModel] = Json.format[EquipmentWithModel]
  def apply(raw: JsValue): Try[EquipmentWithModel] = Try {
    val equipment = Equipment((raw \ "equipment").as[JsValue]).get
    val model     = EquipmentModel((raw \ "model").as[JsValue]).get
    new EquipmentWithModel(equipment, model)
  }
}

case class EquipmentWithModel(equipment: Equipment, model: EquipmentModel) {

  lazy val idToNameMap: Map[String, String] = model.instData.filter(_._2.edgeChannelId.isDefined).map { kv =>
    (kv._2.edgeChannelId.get, kv._1)
  }

  lazy val ids: Set[String] = idToNameMap.keys.toSet

  val id = s"${equipment.id}.${model.id}"

  def isSubscribing(data: EdgeChannelData): Boolean = {
//    println(s"isSubscribing: $ids: ${data.id} = ${ids.contains(data.id)}")
    ids.contains(data.id)
  }

  def input(data: EdgeChannelData): Try[EquipmentData] = {
    val mapped1 = model.instData
      .filter(_._2.edgeChannelId.contains(data.id))
      .mapValues { schema =>
        schema.dataTypeObject.flatMap(data.coerceDataType)
      }
    println(s"mapped1 = $mapped1")
    val mapped = mapped1
      .filter(_._2.isSuccess)
      .mapValues(_.get)
    if (mapped.isEmpty) {
      Failure(new Exception("no data"))
    } else {
      val emd = EquipmentData(equipment, model, mapped, data.timestampNS)
      Success(emd)
    }
  }

  def idToName(id: String): String = {
    idToNameMap.getOrElse(id, id)
  }
}
